#include <stdio.h>
#include "modbus-tcp.h"
#include "modbus.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h>
#include <stdbool.h>
#include "msg_queue_peer.h"
#include "pub_define.h"
#include "shmem.h"


#define ERR_MSG(msg)                           \
    do                                         \
    {                                          \
        fprintf(stderr, "line:%d ", __LINE__); \
        perror(msg);                           \
    } while (0)

union mval
{
    int data_switch;
    int data_val_i;
    double data_val_f;
};

struct mdata
{
    int data_key;           // 数据编号
    char data_name[50];     // 数据名称
    int data_type;  // 数据类型
    union mval val;
};

struct STM32
{
    struct mdata data[14];
};

struct Modbus
{
    struct mdata data[6];
};

//共享内存结构体
struct CJSON
{
    char version[50];      // 版本
    int report_type;   // 报告类型
    int report_period; // 报告周期

    char mqtt_server_addr[50]; // mqtt服务器ip
    int mqtt_server_port;  // mqtt服务器端口号

    char mb_dev_addr[50]; // modbus端ip
    int mb_dev_port;  // modbus端口号

    // STM32
    struct STM32 stm32;

    // modbus
    struct Modbus modbus;
};

//消息结构体
struct mtext
{
    int data_Humidifier;        // 加湿器阈值
    int data_Dehumidifier;      // 除湿器阈值
    int data_TemController;     // 控温仪器阈值
    int Tmp_Hign;               // 温度制冷阈值
    int Tmp_Low;                // 温度制热阈值
    int Hum;                    // 除湿阈值
    int mode;                   // 工作模式(除湿/控温)
    bool mode_aircondition;     // 空调开关状态
    bool state_Humidifier;      // 加湿器工作状态
    bool state_Dehumidifier;    // 除湿器工作状态
    bool state_TemController;   // 控温仪器工作状态
};

//消息队列结构体
struct msgQueue
{
    int key;                   // 对应点表中的key值
    struct mtext text;
    
};

// //接收modbus信息的结构体
// typedef struct ModBusData
// {
//     bool state_Humidifier;      //加湿器工作状态
//     bool state_Dehumidifier;    //除湿器工作状态
//     bool state_TemController;   //控温仪器工作状态
//     int  data_Humidifier;       //加湿器阈值
//     int  data_Dehumidifier;     //除湿器阈值
//     int  data_TemController;    //控温仪器阈值
// }Data_ModBus;

struct shm_param para; //共享内存结构体
struct CJSON jsonRejion ;//共享内存对应结构体
struct msgQueue QueueRejion;//消息队列结构体

int main(int argc, char const *argv[])
{
    //共享内存初始化
    if(shm_init(&para, "shmMery", sizeof(jsonRejion)) == -1)
    {
        ERR_MSG("开辟共享内存失败");
        return -1;
    }
    //映射
    struct CJSON *json = NULL;
    json = shm_getaddr(&para);
    if(json == (struct CJSON *)-1)
    {
        ERR_MSG("映射失败");
        return -1;
    }

    // 创建modbus实例
    modbus_t *ctx;
    ctx = modbus_new_tcp("192.168.58.1", 502);
    if (ctx == NULL)
    {
        printf("modbus new tcp err\n");
        return -1;
    }
    // 设置从机ID
    modbus_set_slave(ctx, 1);
    // 建立连接
    if (modbus_connect(ctx) < 0)
    {
        printf("modbus connect err\n");
        modbus_free(ctx);
        return -1;
    }
    //printf("connect ok\n");

    while(1)
    {
    //读
    uint16_t threshold[3];//阈值
    modbus_read_registers(ctx, 0, 3, threshold);
    //printf("%d %d %d\n", threshold[0], threshold[1], threshold[2]);
    uint8_t state[3];
    modbus_read_bits(ctx, 0, 3, state);
    //printf("%d %d %d \n", state[0], state[1], state[2]);

    //写进结构体
    json->modbus.data[0].val.data_switch = state[0];
    json->modbus.data[1].val.data_switch = state[1];
    json->modbus.data[2].val.data_switch = state[2];
    json->modbus.data[3].val.data_val_i = threshold[0];
    json->modbus.data[4].val.data_val_i = threshold[1];
    json->modbus.data[5].val.data_val_i = threshold[2];

    // 写(消息队列)
    if(msg_queue_msgexist("msgqueue", 100))
    {
    msg_queue_recv("msgqueue", &QueueRejion, sizeof(QueueRejion),1 , 0);
    uint8_t state1[3] = {};
    state1[0] = (uint8_t *)QueueRejion.text.state_Humidifier;
    state1[1] = (uint8_t *)QueueRejion.text.state_Dehumidifier;
    state1[2] = (uint8_t *)QueueRejion.text.state_TemController;
    modbus_write_bits(ctx, 0, 3, state1);

    uint16_t state2[3] = {};
    state2[0] = (uint16_t *)QueueRejion.text.data_Humidifier;
    state2[1] = (uint16_t *)QueueRejion.text.data_Dehumidifier;
    state2[2] = (uint16_t *)QueueRejion.text.data_TemController;
    modbus_write_registers(ctx, 0, 3, state2);
    }
    }

    modbus_free(ctx);
    modbus_close(ctx);
    //shm_del(&para);
    return 0;
}